package pCloud.message;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

/**
 * This represents the data transfered back to the ProxyServer after the access
 * control decision is made (Permit). This is wrapped inside a DataServerReply
 * message, which also contains the decision.
 * 
 * A datbase reply is a map: <joiningColum, values of other column>
 * 
 * The joining column values is used as index, in order to make the joining
 * (later excecuted at the proxy server) easier
 */
public class DatabaseReply extends DatabaseMessage {

	String joiningColumnId;
	HashMap<Object, ArrayList> rowsOfValues;
	ArrayList<String> otherColumns;
	boolean noKey = false;

	public DatabaseReply(String joiningColumnId) {
		this.databaseMsgType = DatabaseMessage.REPLY;
		this.joiningColumnId = joiningColumnId;
		this.rowsOfValues = new HashMap<Object, ArrayList>();

		this.otherColumns = new ArrayList<String>();
		if (joiningColumnId == null)
			this.noKey = true;
	}

	public void addColumnId(String id) {
		this.otherColumns.add(id);
	}

	public ArrayList<String> getNonJoiningColumns() {
		return this.otherColumns;
	}

	public void addKeyValue(Object key) {
		this.rowsOfValues.put(key, new ArrayList());
	}

	public void addSetOfValuesToRow(Object key, ArrayList values) {
		for (int i = 0; i < values.size(); i++)
			this.addValueToRow(key, values.get(i));
	}

	public void addValueToRow(Object key, Object value) {
		this.rowsOfValues.get(key).add(value);
	}

	public HashMap<Object, ArrayList> getRowsOfValues() {
		return this.rowsOfValues;
	}

	public String toString() {
		String output = "";
		if (this.rowsOfValues == null || this.rowsOfValues.size() == 0)
			return output;

		// printing the column ID
		if (!noKey)
			output = output + this.joiningColumnId + "\t";
		for (int i = 0; i < this.otherColumns.size(); i++)
			output = output + otherColumns.get(i) + "\t";
		output += "\n";

		// printing rows
		Object[] keyValues = this.rowsOfValues.keySet().toArray();
		Arrays.sort(keyValues);

		ArrayList rowValues;
		Object key;
		for (int o = 0; o < keyValues.length; o++) {
			key = keyValues[o];
			if (!noKey) // when noKey=true, the key used for the hash table is
						// [1..n]
				output += key + "\t";
			rowValues = this.rowsOfValues.get(key);
			for (int i = 0; i < rowValues.size(); i++)
				output += rowValues.get(i) + "\t";
			output += "\n";
		}
		return output;
	}
}
